#include "Sound.h"
#include <malloc.h>
#include <string.h>
#include "ComponentManager.h"

CSound::CSound():m_sample(0){}
CSound::~CSound()
{
	if(m_sample!=0)
		free(m_sample);
}

bool CSound::loadAndConvertSound(const char* filename, SDL_AudioSpec *spec)
{
	SDL_AudioCVT cvt; // format conversion structure
	SDL_AudioSpec loaded; // format of loaded data
	Uint8* new_buf;

	// Load the sound file
    if ( SDL_LoadWAV(filename, &loaded, &m_sample, &m_length) == NULL ) 
	{
        fprintf(stderr, "Couldn't load %s: %s\n", filename, SDL_GetError());
        return false;
    }

	if(SDL_BuildAudioCVT(&cvt, loaded.format, loaded.channels, loaded.freq, spec->format, spec->channels, spec->freq)<0)
	{
        fprintf(stderr, "Unable to convert sound: %s\n", SDL_GetError());
        return false;
    }

    // Since converting PCM samples can result in more data (for instance,
	// converting 8-bit mono to 16-bit stereo), we need to allocate a new
	// buffer for the converted data. Fortunately, SDL_BuildAudioCVT
	// supplied the necessary information
	cvt.len = m_length;
	new_buf = (Uint8 *)malloc(cvt.len * cvt.len_mult);
	if (!new_buf) 
	{
		fprintf(stderr,"Memory allocation for conversion failed\n");
		SDL_FreeWAV(m_sample);
		return false;
	}

	// Copy the sound samples into the new buffer
	memcpy(new_buf, m_sample, m_length);
	// Perform the conversion on the new buffer
	cvt.buf = new_buf;
	if (SDL_ConvertAudio(&cvt) < 0) 
	{
		fprintf(stderr, "Audio conversion error: %s\n", SDL_GetError());
		free(new_buf);
		SDL_FreeWAV(m_sample);
		return false;
	}
	// Swap the converted data for the original
	SDL_FreeWAV(m_sample);
	m_sample = new_buf;
	m_length *= cvt.len_mult;

	// Success!
	CM.LOGCONSOLE().Log()<<"LOG : AUDIO : "<<filename<<" was loaded and converted successfully\n";
	return true;
}

bool CSound::loadAndConvertSoundFromMemory(char* buffer, int fileSize, SDL_AudioSpec* spec)
{
	SDL_AudioCVT cvt; // format conversion structure
	SDL_AudioSpec loaded; // format of loaded data
	Uint8* new_buf;

	//get file info
	SDL_RWops* file;
	file = SDL_RWFromMem(buffer, fileSize);

	// Load the sound file
    if ( SDL_LoadWAV_RW(file, 1, &loaded, &m_sample, &m_length) == NULL ) 
	{
        fprintf(stderr, "Couldn't load the audio file: %s\n",  SDL_GetError());
        return false;
    }

	if(SDL_BuildAudioCVT(&cvt, loaded.format, loaded.channels, loaded.freq, spec->format, spec->channels, spec->freq)<0)
	{
        fprintf(stderr, "Unable to convert sound: %s\n", SDL_GetError());
        return false;
    }

    // Since converting PCM samples can result in more data (for instance,
	// converting 8-bit mono to 16-bit stereo), we need to allocate a new
	// buffer for the converted data. Fortunately, SDL_BuildAudioCVT
	// supplied the necessary information
	cvt.len = m_length;
	new_buf = (Uint8 *)malloc(cvt.len * cvt.len_mult);
	if (!new_buf) 
	{
		fprintf(stderr,"Memory allocation for conversion failed\n");
		SDL_FreeWAV(m_sample);
		return false;
	}

	// Copy the sound samples into the new buffer
	memcpy(new_buf, m_sample, m_length);
	// Perform the conversion on the new buffer
	cvt.buf = new_buf;
	if (SDL_ConvertAudio(&cvt) < 0) 
	{
		fprintf(stderr, "Audio conversion error: %s\n", SDL_GetError());
		free(new_buf);
		SDL_FreeWAV(m_sample);
		return false;
	}
	// Swap the converted data for the original
	SDL_FreeWAV(m_sample);
	m_sample = new_buf;
	m_length *= cvt.len_mult;

	// Success!
	CM.LOGCONSOLE().Log()<<"LOG : AUDIO : the sound was loaded and converted successfully\n";
	return true;
}



Uint8* CSound::getSample(void)const
{
	return m_sample;
}
Uint32 CSound::getLength(void)const
{
	return m_length;
}
